package com.yayohos.locationmanager.providers.locationprovider;


import com.yayohos.locationmanager.LocationManager;
import com.yayohos.locationmanager.configuration.LocationConfiguration;
import com.yayohos.locationmanager.listener.LocationListener;
import com.yayohos.locationmanager.view.ContextProcessor;

import ohos.aafwk.ability.Ability;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.app.Context;

import java.lang.ref.WeakReference;
import java.util.IllformedLocaleException;

/**
 * LocationProvider
 * @date 2021/5/26
 */
public abstract class LocationProvider {
    private boolean isWaiting = false;
    private LocationConfiguration configuration;
    private ContextProcessor contextProcessor;
    private WeakReference<LocationListener> weakLocationListener;


    /**
     * This method is called immediately once the LocationProvider is set to {@linkplain LocationManager}
     *
     * @param contextProcessor contextProcessor
     * @param configuration    configuration
     * @param listener         listener
     */
    public void configure(ContextProcessor contextProcessor,
                          LocationConfiguration configuration, LocationListener listener) {
        this.contextProcessor = contextProcessor;
        this.configuration = configuration;
        this.weakLocationListener = new WeakReference<>(listener);
        initialize();
    }

    /**
     * This is used for passing object between LocationProviders
     *
     * @param locationProvider LocationProvider
     */
    public void configure(LocationProvider locationProvider) {
        this.contextProcessor = locationProvider.contextProcessor;
        this.configuration = locationProvider.configuration;
        this.weakLocationListener = locationProvider.weakLocationListener;
        initialize();
    }

    /**
     * This method will be used to determine whether any LocationProvider
     * is currently displaying dialog or something.
     *
     * @return isDialogShowing
     */
    public abstract boolean isDialogShowing();

    /**
     * This is where your provider actually starts working
     */
    public abstract void get();

    /**
     * This provider is asked to be canceled all tasks currently running
     * and remove all location update listeners
     */
    public abstract void cancel();

    /**
     * isWaiting
     *
     * @return Returns waiting state
     */
    public boolean isWaiting() {
        return isWaiting;
    }

    /**
     * setWaiting
     *
     * @param waiting Call this method while you begin to process getting location
     *                and call it when at least one location is received
     */
    public void setWaiting(boolean waiting) {
        this.isWaiting = waiting;
    }


    /**
     * Override when you need to handle onAbilityResult such as listening for GPS activation
     *
     * @param requestCode requestCode
     * @param resultCode  resultCode
     * @param data        Intent
     */
    public void onAbilityResult(int requestCode, int resultCode, Intent data) {
    }

    /**
     * This is called right after configurations are set
     */
    public void initialize() {
    }

    /**
     * To remove location updates while getting from GPS or Network Provider
     */
    public void onDestroy() {
        weakLocationListener.clear();
    }

    /**
     * onPause
     */
    public void onPause() {
    }

    /**
     * onResume
     */
    public void onResume() {
    }

    /**
     * getConfiguration
     *
     * @return LocationConfiguration
     */
    protected LocationConfiguration getConfiguration() {
        return configuration;
    }

    /**
     * getListener
     *
     * @return LocationListener
     */
    protected LocationListener getListener() {
        return weakLocationListener.get();
    }

    /**
     * getContext
     *
     * @return Context
     */
    protected Context getContext() {
        return contextProcessor.getContext();
    }

    /**
     * getAbility
     *
     * @return Ability
     */
    protected Ability getAbility() {
        if (contextProcessor == null) {
            throw new IllformedLocaleException("contextProcessor is null");
        }
        return contextProcessor.getAbility();
    }

    /**
     * getAbilitySlice
     *
     * @return AbilitySlice
     */
    protected AbilitySlice getAbilitySlice() {
        if (contextProcessor == null) {
            throw new IllformedLocaleException("contextProcessor is null");
        }
        return contextProcessor.getAbilitySlice();
    }

}